home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 216_01 / kittylnt.c88 < prev    next >
Text File  |  1980-01-01  |  23KB  |  704 lines

  1. /*lintoff*/
  2. /* Saturday, July 12, 1986  3:41 PM                                  */
  3. /*                                                                   */
  4. /*     KITTENSOFT                                                    */
  5. /*                                                                   */
  6. /*     Dan Schechter                                                 */
  7. /*     Route 1 Box 19                                                */
  8. /*     Amenia, North Dakota 58004                                    */
  9. /*     (701) 967-8371                                                */
  10. /*                                                                   */
  11. /*     Do what you like with this program. Please let me know if     */
  12. /*     you find bugs. Exactly as is it compiles under Eco-C88        */
  13. /*     for MS-DOS. I have no idea how portable it is because I do    */
  14. /*     not know how compatible the Ecosoft library functions are     */
  15. /*     with those of other compilers.                                */
  16. /*                                                                   */
  17. /*     This is not intended to be a real LINT program. That would    */
  18. /*     be far beyond my programming ability. This is just a sort     */
  19. /*     of delimiter checker. I have used it only for a short time    */
  20. /*     but I have found it useful. I hope you will also.             */
  21. /*                                                                   */
  22. /*     Following are some general comments about this program:       */
  23. /*
  24. When checking for proper line termination it returns <good> on
  25. end-of-comment marker. This might not be the best choice as it could mask
  26. an error on the same line (when a short comment is on the same line as
  27. a line of code).
  28.  
  29. It expects if, for, and while loops to be terminated by closing parenthesis
  30. (no semicolon) if and only if the loop declaration has no following statement.
  31.  
  32.     Example 1:    if (a==b)
  33.                 x=y;
  34.  
  35.     Example 2:    if (a==b) x=y;
  36.  
  37. Both the above are correct and will not cause error messages.
  38.  
  39.     Example 3:    while(a[i++]!=0);
  40.  
  41. In the above, the programmer wants to increment i until a[i] is 0,
  42. thus the semicolon is correct, but the lint program expects any kind of
  43. loop to control a statement or block of statements, and so generates
  44. the error message "Check line termination".
  45.  
  46. Sometimes, line labels will generate spurious error messages.
  47.  
  48. It will check printf(), fprintf(), sprintf and scanf() to see that the number
  49. of parameters matches the number of <%> conversion characters. However it
  50. does NOT check for type consistency, or anything about parameters 
  51. passed to functions. It will check to make sure that a for() loop has
  52. exactly two semicolons inside the parentheses. A spurious error message
  53. will be generated if a function name ends in "for" as the program thinks
  54. it is a for() loop.
  55.  
  56. It will check for the balance of () parentheses, [] brackets, "" quote marks, 
  57. and {} braces. Spurious error messgaes may be generated if any of these are
  58. used as text characters. Parentheses, braces, and quotes, but not brackets,
  59. may be balanced on following lines if the LAST character on a line is a
  60. backslash. Even white space following a backslash is not permitted. This is
  61. consistent with Aztec C. This program will flag white space following the 
  62. last backslash on a line. I originally wrote the program for Aztec C. This
  63. copy is modified for Ecosoft C. Ecosoft C neither needs nor permits a
  64. backslash as a line-continuation character. Thus you will get spurious error 
  65. messages if you continue a logical line to the next physical line. You may 
  66. wish to fiddle with this. See querybks() below.
  67.  
  68. It will flag a line that appears to be a function declaration with a
  69. semicolon. This may generate some spurious error messages. Again, because
  70. Ecosoft allows longer function names than Manx does, spurious error messages 
  71. will result if you use longer function names. And the program may fail to
  72. flag a genuine error: if you mistakenly put a semicolon after a function
  73. declaration (as I sometimes do reflexively) this program can flag it only
  74. if the function name is 8 characters or less. See the function called
  75. funcdecl() below to change this. Note however that increasing the 8 character
  76. limit may result in other spurious error messages. Also be sure to
  77. see askfunc() to keep things consistent. Hack away!
  78.  
  79. It will flag nested or unbalanced comment markers.
  80.  
  81. It will not check for undeclared variables.
  82.  
  83. It does not recognize the comma that terminates lines in initializing
  84. statements as permissable. Thus initializers will generate spurious error
  85. messages. I suggest toggling lint off for these. 
  86.  
  87. Most of the time it will find the syntax mistakes I make most often:
  88. unbalanced parentheses, brackets, braces, and quotes; missing semicolons,
  89. semicolons after function declarations, nested comments, parameters
  90. left out of printf() statements, and too many or two few semicolons
  91. inside for() statements. In spite of all the limitations, I have found
  92. it to be extremely useful, perhaps because I am such a careless typist.
  93.  
  94. Checking is toggled on and off with the words                         */
  95. /*linton*/
  96. /*lintoff*/                                                           /*
  97. which must appear starting at column 1, between comment markers,
  98. without spaces. They may not be nested.
  99.                                                                       */
  100. /*linton*/
  101.  
  102. #include <stdio.h>
  103. #include <string.h>
  104. #define BELL 7
  105. int errno;
  106. main(n,arg)
  107. int n;
  108. char **arg;
  109. {
  110.     int i,op=0,cp=0,ob=0,cb=0,os=0,cs=0,cmt=0,sq=0,quo=0,quot=0,l=0,conline=0;
  111.     char disab=0,q,string[500],fn[20],*fgets(),*r=1,cmtb=0;
  112.     FILE *fp;
  113.  
  114. /* If there is a file name on the command line it will use it. Otherwise */
  115. /* it will ask for a file name                                           */
  116.  
  117.     if (n==2) strcpy(fn,arg[1]);
  118.     else getfn(fn);
  119. o:    if ((fp=fopen(fn,"r"))==0){
  120.         printf("Can't find %s  errno=%d",fn,errno);
  121.         errno=0;
  122.         getfn(fn);
  123.         goto o;
  124.     }
  125.     
  126.     while(r){
  127.         l++;
  128.         for (i=0;i<500;i++) string[i]='\n';
  129.  
  130. /* The following gets one line of source code */
  131.  
  132.         r=fgets(string,490,fp);
  133.  
  134. /* It ignores lines beginning with # because they usually require no */
  135. /* special line termination:                                         */
  136.  
  137.         if (string[0]=='#') continue;
  138.         if ((i=strncmp(string,"/*lintoff*/",11))==0) {
  139.             disab=1;
  140.  
  141. /* conline keeps track of how many lines have been printed, so the */
  142. /* program can pause for you to read the error messages.           */
  143.  
  144.             conline++;
  145.             printf("%s line: %d --> LINT TURNED OFF.\n\n",fn,l);
  146.             if (conline>9) pause(&conline);
  147.         }
  148.         if ((i=strncmp(string,"/*linton*/",10))==0) {
  149.             disab=0;
  150.             conline++;
  151.             printf("%s line: %d --> LINT TURNED BACK ON.\n\n",fn,l);
  152.             if (conline>9) pause(&conline);
  153.         }
  154.         if (disab) continue;
  155.         q=cktsp(string);
  156.         if (q=='b'){
  157.             conline++;
  158.             printf("%s line: %d --> White space after backslash:\n%s",fn,l,string);
  159.             q='r';
  160.             if (conline>9) pause(&conline);
  161.         }
  162.         diddle(string);
  163.  
  164. /* This is to skip blank lines:  */ 
  165.  
  166.         if (string[0]=='\n') continue;
  167.         q=endcheck(string);    
  168.         if (  (q=='f') && ((op!=cp)||(ob!=cb))  ) {
  169.             conline++;
  170.             printf("%s line: %d --> New function declaration. --> %sUnbalanced parentheses<%d> or wavy brackets<%d> in the preceding function.\n",fn,l,string,(op-cp),(ob-cb));
  171.             if (conline>9) pause(&conline);
  172.             op=0;cp=0;ob=0;cb=0;os=0;cs=0;
  173.         }
  174.         if (q=='b'){
  175.             q=endexcpt(string);
  176.             if (q=='b'){                     
  177.                 conline++;
  178.                 printf("%s line: %d --> check line termination:\n%s",fn,l,string);
  179.                 if (conline>9) pause(&conline);
  180.             }                                
  181.             q='r';
  182.         }
  183.         if (q=='g'){
  184.             q=loopwscn(string);
  185.             if (q=='b'){                     
  186.                 conline++;
  187.                 printf("%s line: %d --> check line termination:\n%s",fn,l,string);
  188.                 if (conline>9) pause(&conline);
  189.             }                                
  190.             q='r';
  191.         }
  192.  
  193. /* These keep track of brackets: */
  194.  
  195.         for (i=0;string[i]!='\n';i++){
  196.             if (string[i]=='(') op++;
  197.             if (string[i]==')') cp+